package com.mes.cloud.base.feign;

import feign.MethodMetadata;
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import java.lang.annotation.Annotation;
import java.util.concurrent.atomic.LongAdder;

public class FormParamParameterProcessor implements AnnotatedParameterProcessor {

    public static final String AUTO_NAME_PREFIX = "_$FormParam$_";

    public static final String POST = RequestMethod.POST.name();

    private static final Class<FormParam> ANNOTATION = FormParam.class;

    private static final String CONTENT_TYPE_VALUE = MediaType.APPLICATION_FORM_URLENCODED_VALUE;

    private static LongAdder longAdder = new LongAdder();

    @Override
    public Class<? extends Annotation> getAnnotationType() {
        return ANNOTATION;
    }

    @Override
    public boolean processArgument(AnnotatedParameterContext context, Annotation annotation) {
        MethodMetadata data = context.getMethodMetadata();
        if (!POST.equalsIgnoreCase(data.template().method())) {
            throw new IllegalStateException("FormParam annotation need request method [POST].");
        }

        data.template().header(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_VALUE);

        FormParam formParam = ANNOTATION.cast(annotation);
        String name = formParam.value();

        if (StringUtils.hasText(name)) {
            context.setParameterName(name);
            data.formParams().add(name);
//            if (data.formParams().stream().noneMatch(paramName -> paramName.startsWith(AUTO_NAME_PREFIX))) {
//                data.template().bodyTemplate(appendTemplate(data.template().bodyTemplate(), name));
//            }
        } else {
            longAdder.increment();
            String paramName = String.format("%s_%d", AUTO_NAME_PREFIX, longAdder.longValue());
            context.setParameterName(paramName);
            data.formParams().add(paramName);
//            data.template().bodyTemplate(null);
        }

        data.template().bodyTemplate(null);
        return true;
    }

    private String appendTemplate(String template, String name) {
        StringBuilder body = new StringBuilder();
        if (template != null) {
            body.append(template).append("&");
        }
        body.append(name).append("={").append(name).append("}");
        return body.toString();
    }
}